<?php
class ProductsSerialsController extends AppController {
    var $name = 'ProductsSerials';

    var $viewPath = 'its/inventories/products_serials';

    var $uses = array('ProductSerial', 'Product', 'Warehouse', 'Location', 'CustLocation', 'CustProductSite', 'SD', 'CPSLocation');

    function popup_view($product_id = null) {
        $this->layout = 'popup';
        $this->Product->id = $product_id;
        $this->set('popupTitle', 'Inventory Index for ' . $this->Product->field('part_no'));
        $this->set('product_id', $product_id);
        $this->set('popupWidth', '900');

    }

    function popup_cust_view($cust_product_site_id = null) {
        $this->layout = 'popup';
        $this->CustProductSite->id = $cust_product_site_id;
        $this->Product->id = $this->CustProductSite->field('product_id');
        $this->set('popupTitle', 'Inventory Index for ' . $this->CustProductSite->field('stock_code'));
        $this->set('cust_product_site_id', $cust_product_site_id);
        $this->set('popupWidth', '900');

        $this->_cust_render_handler($cust_product_site_id);
    }

    /**
     * เลือกหน้า view ที่จะแสดงผล
     *  ฝั่ง Customer
     */
    function _cust_render_handler($cust_product_site_id) {
        $this->CustProductSite->id = $cust_product_site_id;
        $product_id = $this->CustProductSite->field('product_id');
        if (isset($this->passedArgs['cust_stock_in_id'])) {
            // มาจากหน้า ประเภท Cust Stock in
            $this->setAction('cust_stock_in_view', $product_id, $this->passedArgs['cust_stock_in_id'], $this->passedArgs['cust_stock_in_type']);
        } elseif (isset($this->passedArgs['cust_stock_out_id'])) {
            // มาจากหน้า Cust Stock out
            $this->setAction('cust_stock_out_view', $product_id, $this->passedArgs['cust_stock_out_id'], $this->passedArgs['cust_stock_out_type']);
        } elseif (isset($this->passedArgs['cust_reserve_id'])) {
            // มาจากหน้า Cust Reserve
            $this->setAction('cust_reserve_view', $product_id, $this->passedArgs['cust_reserve_id']);
        } else {    // มาจากหน้า Cust Product Site
            $this->setAction('cust_view', $cust_product_site_id);
        }
    }

    /**
     * view สำหรับ หน้า Product
     * @param <type> $product_id
     */
    function view($product_id) {
        $options = array();
        $options['order'] = array('stock_out_priority ASC');
        $options['conditions']['ProductSerial.product_id'] = $product_id;
        // แสดงเฉพาะที่ยังไม่ได้ stock out
        $options['conditions']['its_stock_out_id'] = null;
        $options['contain'] = array('Location' => array('Warehouse'));

        $this->_findProductSerial($product_id, $options);
        $this->set('warehouses', $this->Warehouse->find('list'));
    }

    /**
     * view สำหรับ หน้าประเภท its_stock_in
     * @param <type> $product_id
     * @param <type> $its_stock_in_id
     * @param <type> $its_stock_in_type
     * @param boolean $return แสดงเฉพาะรายการที่ถูก return หรือไม่
     */
    function its_stock_in_view($product_id, $its_stock_in_id, $its_stock_in_type) {
        $options = array();
        $options['order'] = array('stock_out_priority ASC');
        $options['conditions']['ProductSerial.product_id'] = $product_id;
        $options['conditions']['ProductSerial.its_stock_in_id'] = $its_stock_in_id;
        $options['conditions']['ProductSerial.its_stock_in_type'] = $its_stock_in_type;
//        $options['conditions']['ProductSerial.is_active_flag'] = true;
        $options['contain'] = array('Location');

        $this->_findProductSerial($product_id, $options);
        $this->set('its_stock_in_id', $its_stock_in_id);
        $this->set('its_stock_in_type', $its_stock_in_type);
    }

    /**
     * view สำหรับ หน้า Dispatch
     * @param <type> $product_id
     * @param <type> $its_stock_out_id
     * @param <type> $its_stock_out_type
     * @param boolean $return แสดงเฉพาะรายการที่ถูก return หรือไม่
     */
    function dispatch_view($product_id, $its_stock_out_id, $its_stock_out_type) {
        $options = array();
        $options['order'] = array('stock_out_priority ASC');
        $options['conditions']['ProductSerial.its_stock_out_id'] = $its_stock_out_id;
        $options['conditions']['ProductSerial.its_stock_out_type'] = $its_stock_out_type;

        $this->_findProductSerial($product_id, $options);
        $this->set('its_stock_out_id', $its_stock_out_id);
        $this->set('its_stock_out_type', $its_stock_out_type);
        if ($its_stock_out_type == SD::ITS_STOCK_OUT_TYPE) {
            $this->render('supplier_dispatch_view');
        }
    }

    /**
     * method ภายในที่ใช้ร่วมกันในการ query ProductSerial
     * @param array $options option ในการ query
     */
    function _findProductSerial($product_id, $options) {
        // มีการแสดงเฉพาะ Warehouse หรือไม่
        if(!empty($this->passedArgs['warehouse_id'])) {
            $options['conditions']['warehouse_id'] = $this->passedArgs['warehouse_id'];
            $this->set('selected_warehouse', $this->passedArgs['warehouse_id']);
            // option list สำหรับเปลี่ยน Location code
            $this->set('locations', $this->_getAjaxCollectionLocations($this->passedArgs['warehouse_id']));
        } else {
            $this->set('selected_warehouse', null);
            $this->set('locations', $this->_getAjaxCollectionLocations());
        }


        $this->data = $this->ProductSerial->find('all', $options);
        $sops = $this->_getAjaxCollectionStockOutPriority();

        $this->set('stock_out_priorities', $sops);
        $this->set('product_id', $product_id);

        // เก็บ part action ที่เรียกไว้ใน Session กรณีเปลี่ยน SoP จะได้ request หน้ากลับมาแสดงผลได้ถูก
        $this->Session->write($this->name, substr($this->here, stripos($this->here, '/', 2) + 1));
    }

    /**
     * ใช้ใน AjaxInplaceEditor option list สำหรับ เปลี่ยน Stock out Priority
     * Generate option list format ที่ใช้ใน AjaxCollectionEditor
     */
    function _getAjaxCollectionStockOutPriority() {
        $sops = array();
        $product_serial_count = count($this->data);
        for($i = 0; $i < $product_serial_count; ++$i) {
            $sops[] = array($this->data[$i]['ProductSerial']['stock_out_priority'], $i + 1 );
        }
        return $sops;
    }

    /**
     * ใช้ใน AjaxInplaceEditor option list สำหรับ location ทุก warehouse
     * Generate option list format ที่ใช้ใน AjaxCollectionEditor
     * @param <type> $warehouse_id
     */
    function _getAjaxCollectionLocations($warehouse_id = null) {
        $locations = array();
        $l = array();
        $this->Warehouse->bindModel(array('hasMany' => array('Location')));
        $this->Warehouse->contain(array('Location.id', 'Location.name'));
        if ($warehouse_id != null) {
            $l = $this->Warehouse->find('all', array('conditions' => array('Warehouse.id' => $warehouse_id)));
        } else {
            $l = $this->Warehouse->find('all');
        }

        foreach($l as $k => $warehouse) {
            $warehouse_id = $warehouse['Warehouse']['id'];
            foreach($warehouse['Location'] as $k => $loc) {
                $locations[$warehouse_id][] = array($loc['id'], $loc['name']);
            }
        }
        return $locations;
    }

    /**
     * เปลี่ยน SoP ของ ProductSerial ที่เลือก จากหน้า ItsStockIn
     * @param int $product_serial_id ที่ต้องการเปลี่ยน
     * @param int $old_sop
     */
    function change_its_stock_in_sop($product_serial_id, $old_sop, $its_stock_in_id, $its_stock_in_type) {
        $options = array();
        $options['conditions']['its_stock_in_id'] = $its_stock_in_id;
        $options['conditions']['its_stock_in_type'] = $its_stock_in_type;
        $this->_change_sop($product_serial_id, $old_sop, $options);
    }

    /**
     * เปลี่ยน SoP ของ ProductSerial ที่เลือก จากหน้า Dispatch
     * @param int $product_serial_id ที่ต้องการเปลี่ยน
     * @param int $old_sop
     */
    function change_dispatch_sop($product_serial_id, $old_sop, $its_stock_out_id, $its_stock_out_type) {
        $options = array();
        $options['conditions']['its_stock_out_id'] = $its_stock_out_id;
        $options['conditions']['its_stock_out_type'] = $its_stock_out_type;
        $this->_change_sop($product_serial_id, $old_sop, $options);
    }

    /**
     * เปลี่ยน SoP ของ ProductSerial ที่เลือก จากหน้า Product
     * @param int $product_serial_id ที่ต้องการเปลี่ยน
     * @param int $old_sop
     */
    function change_stock_out_priority($product_serial_id, $old_sop) {
        $options = array();
        $options['conditions']['its_stock_out_id'] = null;      // แสดงเฉพาะที่ยังไม่ได้ stock out
        $this->_change_sop($product_serial_id, $old_sop, $options);
    }

    function _change_sop($product_serial_id, $old_sop, $options) {
        $product_id = $this->passedArgs['product_id'];
        $new_sop = $this->params['form']['value'];
        $step;
        $options['conditions']['ProductSerial.product_id'] = $product_id;
        if ($new_sop < $old_sop) {                          // เลื่อน sop ขึ้น เลือก Product Serial ถึง อันเดิม
            $options['conditions']['stock_out_priority >='] = $new_sop;
            $options['conditions']['stock_out_priority <'] = $old_sop;
            $step = 1;                                      // เลื่อน ProductSerial SoP แต่ละชิ้นขึ้น
        } elseif($new_sop > $old_sop) {                     // เลื่อน sop ลง เลือก Product Serial ถึง อันเดิม
            $options['conditions']['stock_out_priority >'] = $old_sop;
            $options['conditions']['stock_out_priority <='] = $new_sop;
            $step = -1;                                     // เลื่อน ProductSerial SoP แต่ละชิ้นลง
        } else {                                            // เลือก SoP เดิม ไม่ต้องเปลี่ยน Product Serial อันอื่น
            $options['conditions']['stock_out_priority ='] = false;
        }
        $options['order'] = array('stock_out_priority DESC');
        $options['fields'] = array('id', 'stock_out_priority');

        $this->ProductSerial->contain();
        $PSs = $this->ProductSerial->find('all', $options);
        foreach($PSs as $ps) {
            // ลด Product Serial sop ลงชิ้นละ 1
            $this->ProductSerial->id = $ps['ProductSerial']['id'];
            $this->ProductSerial->saveField('stock_out_priority', $ps['ProductSerial']['stock_out_priority'] + $step);
        }

        // ปรับ stock our priority ที่เลือก
        $this->ProductSerial->id = $product_serial_id;
        $this->ProductSerial->saveField('stock_out_priority', $new_sop);

        // กลับไป request หน้าใหม่
        $action = $this->Session->read($this->name);
        echo '<script type="text/javascript">requestUpdater("divProductSerial", "' . $action . '");</script>';
        echo 'Loading...';
        exit;
    }

    function inplace_editor($field, $id) {
        if (trim($this->params['form']['value']) == 'N/A') {
            echo 'N/A';
            exit;
        }
        parent::inplace_editor($this->ProductSerial, $field, $id);
    }

    /**
     * เปลี่ยน Location ของ ProductSerial ที่เลือก
     * @param int $product_serial_id
     */
    function change_location($product_serial_id) {
        $this->ProductSerial->id = $product_serial_id;
        $new_location_id = $this->params['form']['value'];
        $this->ProductSerial->saveField('location_id', $new_location_id);

        $this->Location->id = $new_location_id;
        echo $this->Location->field('name');
        exit;
    }

    /**
     * method ภายในที่ใช้ร่วมกันในการ query ProductSerial ฝั่ง Customer
     * @param array $options option ในการ query
     */
    function _findCustProductSerial($product_id, $options) {
        $this->data = $this->ProductSerial->find('all', $options);

        // เช็คว่า Customer ดู site ไหนอยู่
        $site_id = $this->Session->check('Auth.User.Extend.view_site_inventory')?
                $this->Session->read('Auth.User.Extend.view_site_inventory'): $this->Auth->user('site_id');
        // option list สำหรับเปลี่ยน Cust Location
        $this->set('custLocations', $this->_getAjaxCollectionCustLocations($site_id));
        $this->set('product_id', $product_id);

        // เก็บ part action ที่เรียกไว้ใน Session กรณีเปลี่ยน SoP จะได้ request หน้ากลับมาแสดงผลได้ถูก
        $this->Session->write($this->name, substr($this->here, stripos($this->here, '/', 2) + 1));
    }

    /**
     * ใช้ใน AjaxInplaceEditor option list สำหรับ Customer location
     * Generate option list format ที่ใช้ใน AjaxCollectionEditor
     * @param int $site_id
     */
    function _getAjaxCollectionCustLocations($site_id = null) {
        $this->CustLocation->contain();
        $l = $this->CustLocation->find('all', array('conditions' => array('site_id' => $site_id)));

        $locations = array();
        foreach($l as $k => $loc) {
            $locations[] = array($loc['CustLocation']['id'], $loc['CustLocation']['name']);
        }
        return $locations;
    }

    /**
     * เปลี่ยน CustLocation ของ ProductSerial ที่เลือก
     * @param int $product_serial_id
     */
    function change_cust_location($product_serial_id) {
        $this->ProductSerial->id = $product_serial_id;
        $new_location_id = $this->params['form']['value'];
        $this->ProductSerial->saveField('cust_location_id', $new_location_id);
        // เพิ่มลง Default location ของ CPS
        $cust_product_site_id = $this->ProductSerial->field('cust_product_site_id');
        if ($this->CPSLocation->addLocation($cust_product_site_id, $new_location_id)) {
            // มีการ เพิ่ม default location refresh รายการที่แสดงบนหน้าจอ
            echo '<script type="text/javascript">requestUpdater("divCPSLocations", "its_cust_product_sites/display_locations/' . $cust_product_site_id . '");</script>';
        }

        $this->CustLocation->id = $new_location_id;
        echo $this->CustLocation->field('name');
        exit;
    }

    /**
     * view สำหรับ หน้าประเภท cust_stock_in
     * @param int $product_id
     * @param int $cust_stock_in_id
     * @param string $cust_stock_in_type
     * @param boolean $return แสดงเฉพาะรายการที่ถูก return หรือไม่
     */
    function cust_stock_in_view($product_id, $cust_stock_in_id, $cust_stock_in_type) {
        $options = array();
        $options['order'] = array('stock_out_priority ASC');
        $options['conditions']['ProductSerial.product_id'] = $product_id;
        $options['conditions']['ProductSerial.cust_stock_in_id'] = $cust_stock_in_id;
        $options['conditions']['ProductSerial.cust_stock_in_type'] = $cust_stock_in_type;
        $options['contain'] = array('CustLocation');

        $this->_findCustProductSerial($product_id, $options);
        $this->set('cust_stock_in_id', $cust_stock_in_id);
        $this->set('cust_stock_in_type', $cust_stock_in_type);
    }

    /**
     * view สำหรับ หน้าประเภท cust_stock_out
     * @param int $product_id
     * @param int $cust_stock_out_id
     * @param string $cust_stock_out_type
     */
    function cust_stock_out_view($product_id, $cust_stock_out_id, $cust_stock_out_type) {
        $options = array();
        $options['order'] = array('stock_out_priority ASC');
        $options['conditions']['ProductSerial.product_id'] = $product_id;
        $options['conditions']['ProductSerial.cust_stock_out_id'] = $cust_stock_out_id;
        $options['conditions']['ProductSerial.cust_stock_out_type'] = $cust_stock_out_type;
        $options['contain'] = array('CustLocation');

        $this->_findCustProductSerial($product_id, $options);
        $this->set('cust_stock_out_id', $cust_stock_out_id);
        $this->set('cust_stock_out_type', $cust_stock_out_type);
    }

    /**
     * view สำหรับ หน้า cust reserve
     * @param int $product_id
     * @param int $cust_reserve_id
     */
    function cust_reserve_view($product_id, $cust_reserve_id) {
        $options = array();
        $options['order'] = array('stock_out_priority ASC');
        $options['conditions']['ProductSerial.product_id'] = $product_id;
        $options['conditions']['ProductSerial.cust_reserve_id'] = $cust_reserve_id;
        $options['contain'] = array('CustLocation');

        $this->_findCustProductSerial($product_id, $options);
        $this->set('cust_reserve_id', $cust_reserve_id);
    }

    /**
     * view สำหรับ หน้า CustProductSite
     *
     * @param int $cps_id CustProductSite id
     * @param boolean $show_cust_reserve แสดงรายการที่จองไว้ด้วยหรือไม่
     *
     */
    function cust_view($cps_id) {
        $options = array();
        $options['order'] = array('stock_out_priority ASC');
        $options['conditions']['ProductSerial.cust_product_site_id'] = $cps_id;
        // แสดงเฉพาะที่อยู่ในคลัง (stock_in เข้าไปแล้ว)
        // ยังไม่ถูก stock out และไม่ได้ถูก return (is_active_flag = true)
        $options['conditions']['cust_stock_in_id !='] = null;
        $options['conditions']['cust_stock_out_id'] = null;
        $options['conditions']['is_active_flag'] = true;
        if (isset($this->passedArgs['limit'])) {
            $options['limit'] = $this->passedArgs['limit'];
        }

        // ไม่ต้องแสดงรายการที่จองแล้ว
        if (isset($this->passedArgs['show_cust_reserve']) && $this->passedArgs['show_cust_reserve'] == false) {
            $options['limit'] = $this->passedArgs['limit'];
            $options['conditions']['cust_reserve_id'] = null;
        }

        $options['contain'] = array('CustLocation');
        $this->set('cps_id', $cps_id);
        $this->CustProductSite->id = $cps_id;
        $product_id = $this->CustProductSite->field('product_id');
        $this->_findCustProductSerial($product_id, $options);
        $this->set('sops', $this->_getAjaxCollectionStockOutPriority());
    }

    /**
     * เปลี่ยน SoP ของ ProductSerial ที่เลือก จากหน้า CustProductSite
     * @param int $product_serial_id ที่ต้องการเปลี่ยน
     * @param int $old_sop
     */
    function change_cust_stock_out_priority($product_serial_id, $old_sop) {
        $options = array();
        $options['conditions']['cust_stock_out_id'] = null;
        $options['conditions']['cust_stock_in_id <>'] = null;
        $options['conditions']['is_active_flag'] = true;
        $this->_change_cust_sop($product_serial_id, $old_sop, $options);
    }

    function _change_cust_sop($product_serial_id, $old_sop, $options) {
        $cps_id = $this->passedArgs['cust_product_site_id'];
        $new_sop = $this->params['form']['value'];
        $step;
        $options['conditions']['ProductSerial.cust_product_site_id'] = $cps_id;
        $options['conditions']['ProductSerial.is_active_flag'] = true;
        if ($new_sop < $old_sop) {                          // เลื่อน sop ขึ้น เลือก Product Serial ถึง อันเดิม
            $options['conditions']['stock_out_priority >='] = $new_sop;
            $options['conditions']['stock_out_priority <'] = $old_sop;
            $step = 1;                                      // เลื่อน ProductSerial SoP แต่ละชิ้นขึ้น
        } elseif($new_sop > $old_sop) {                     // เลื่อน sop ลง เลือก Product Serial ถึง อันเดิม
            $options['conditions']['stock_out_priority >'] = $old_sop;
            $options['conditions']['stock_out_priority <='] = $new_sop;
            $step = -1;                                     // เลื่อน ProductSerial SoP แต่ละชิ้นลง
        } else {                                            // เลือก SoP เดิม ไม่ต้องเปลี่ยน Product Serial อันอื่น
            $options['conditions']['stock_out_priority ='] = false;
        }
        $options['order'] = array('stock_out_priority DESC');
        $options['fields'] = array('id', 'stock_out_priority');

        $this->ProductSerial->contain();
        $PSs = $this->ProductSerial->find('all', $options);
        foreach($PSs as $ps) {
            // ลด Product Serial sop ลงชิ้นละ 1
            $this->ProductSerial->id = $ps['ProductSerial']['id'];
            $this->ProductSerial->saveField('stock_out_priority', $ps['ProductSerial']['stock_out_priority'] + $step);
        }

        // ปรับ stock our priority ที่เลือก
        $this->ProductSerial->id = $product_serial_id;
        $this->ProductSerial->saveField('stock_out_priority', $new_sop);

        // กลับไป request หน้าใหม่
        $action = $this->Session->read($this->name);
        echo '<script type="text/javascript">requestUpdater("divProductSerial", "' . $action . '");</script>';
        echo 'Loading...';
        exit;
    }
}
?>
